/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.alias;

import com.alias.deals.Deal;
import com.alias.deals.Party;
import com.alias.products.BootsProduct;
import com.alias.products.FotoProduct;
import java.util.*;

/**
 * Dealling program main class. All business logic are here.
 *
 * @author DioDread
 */
public class DealingProgram {
    private int dealsCount;
    private List<Deal> deals = new ArrayList<Deal>();
    private static InputReadParse input = new InputReadParse();
    private Map<FotoProduct, Integer> fotoProducts = new HashMap<FotoProduct, Integer>();
    private Map<BootsProduct, Integer> bootsProducts = new HashMap<BootsProduct, Integer>();

    public int getDealsCount() {
        return dealsCount;
    }

    public void setDealsCount(int dealsCount) {
        this.dealsCount = dealsCount;
    }

    private DealingProgram() {
    }

    private Deal inputDeal() {

        Map<FotoProduct, Integer> tempFotoProducts = new HashMap<FotoProduct, Integer>();
        Map<BootsProduct, Integer> tempBootsProducts = new HashMap<BootsProduct, Integer>();

        System.out.println("Input type of products (1 is Photo products, 0 is shoes)");
        int tail = 0, prodtype = Integer.valueOf(input.getParsedInput());
        System.out.println("Input count of product batches");
        int productCount = Integer.valueOf(input.getParsedInput());
        Deal d;
        String checker;
        Integer fotoQuantity;
        Integer bootsQuantity;
        if (prodtype == 1) {
            FotoProduct pr;

            System.out.println("You choose camera");
            while (tail < productCount) {
                System.out.println("Input quantity of product");
                fotoQuantity = Integer.valueOf(input.getParsedInput());
                if (isFotoProductExist(pr = inputFotoProduct())) {
                    System.out.println("Same product already exist. If you want use it press Y, if you want input new specified product press N");
                    checker = input.getInput();
                    if (checker.equals("Y")) {
                        Set<FotoProduct> fotoSet = this.fotoProducts.keySet();
                        for (FotoProduct fr : fotoSet) {
                            if (fr.getTitle().equals(pr.getTitle())) {
                                tempFotoProducts.put(fr, fotoQuantity);
                                tail++;
                            }
                        }
                    }
                } else {
                    putFotoProduct(pr, fotoQuantity);
                    tempFotoProducts.put(pr, fotoQuantity);
                    tail++;
                }
            }
            d = new Deal(inputParty("Sell"), inputParty("Buy"), tempFotoProducts, null);
        } else {
            BootsProduct pr;

            System.out.println("You choose boots");
            while (tail < productCount) {
                System.out.println("Input quantity of product");
                bootsQuantity = Integer.valueOf(input.getParsedInput());
                if (isBootsProductExist(pr = inputBootsProduct())) {
                    System.out.println("Same product already exist. If you want use it press Y, if you want input new specified product press N");
                    checker = input.getInput();
                    if (checker.equals("Y")) {
                        Set<BootsProduct> bootsSet = this.bootsProducts.keySet();
                        for (BootsProduct fr : bootsSet) {
                            if (fr.getTitle().equals(pr.getTitle())) {
                                System.out.println("Input quantity of product");
                                tempBootsProducts.put(fr, bootsQuantity);
                                tail++;
                            }
                        }
                    }
                } else {
                    putBootsProduct(pr, bootsQuantity);
                    tempBootsProducts.put(pr, bootsQuantity);
                    tail++;
                }
            }
            d = new Deal(inputParty("Sell"), inputParty("Buy"), null, tempBootsProducts);
        }
        return d;
    }

    private Party inputParty(String instruction) {
        int spaces;
        if ("Buy".equals(instruction)) {
            Map<String, String> addInfo = new HashMap<String, String>();
            System.out.println("Input buyer name here");
            String buyerName = input.getInput();
            System.out.println("Input buyer address here");
            String buyerAddress = input.getInput();
            Party buyer = new Party();         //inputParty("buyer / seller")
            buyer.setName(buyerName);          //
            buyer.setAdress(buyerAddress);
            System.out.println("Input buyer additional info first key then value. Type Stop to end input");
            while (true) {

                StringBuilder key = new StringBuilder(input.getInput());
                if (key.toString().equals("Stop")) {
                    break;
                }
                StringBuilder value = new StringBuilder(input.getInput());
                if (value.toString().equals("Stop")) {
                    break;
                }
                spaces = key.length() - value.length();

                if (spaces > 0) {
                    for (int k = 0; k < spaces; k++) {
                        value.append(" ");
                    }

                } else {
                    for (int k = 0; k < spaces * -1; k++) {
                        key.append(" ");
                    }
                }
                addInfo.put(String.valueOf(key), String.valueOf(value));
                System.out.println("Input new key and value pair. Type Stop to finish input");
            }
            buyer.setAdditionalInfo(addInfo);
            return buyer;
        } else if ("Sell".equals(instruction)) {
            Map<String, String> addInfo = new LinkedHashMap<String, String>();
            System.out.println("Input seller name here");
            String sellerName = input.getInput();
            System.out.println("Input seller address here");
            String sellerAddress = input.getInput();
            Party seller = new Party();
            seller.setName(sellerName);
            seller.setAdress(sellerAddress);
            System.out.println("Input input additional buyer info, first key then value. Type Stop to finish input");
            while (true) {

                StringBuilder key = new StringBuilder(input.getInput());
                if (key.toString().equals("Stop")) {
                    break;
                }
                StringBuilder value = new StringBuilder(input.getInput());
                if (value.toString().equals("Stop")) {
                    break;
                }
                spaces = key.length() - value.length();

                if (spaces > 0) {
                    for (int k = 0; k < spaces; k++) {
                        value.append(" ");
                    }

                } else {
                    for (int k = 0; k < spaces * -1; k++) {
                        key.append(" ");
                    }
                }
                addInfo.put(String.valueOf(key), String.valueOf(value));
                System.out.println("Input new key and value pair. Type Stop to finish input");
            }
            seller.setAdditionalInfo(addInfo);
            return seller;
        } else {
            System.out.println("Wrong instruction");
        }
        return null;
    }

    private FotoProduct inputFotoProduct() {
        System.out.println("Input products here");
        String title = input.getInput();
        String priceStr = input.getParsedInput();
        System.out.println("Input megapixels count");
        String megapx = input.getParsedInput();
        System.out.println("Input type of camera (true is digital or false is analog)");
        String digital = input.getInput();
        FotoProduct pr = new FotoProduct();
        pr.setTitle(title);
        pr.setPrice(Double.valueOf(priceStr));
        pr.setMegapx(Float.valueOf(megapx));
        pr.setDigital(Boolean.valueOf(digital));
        System.out.println("-----------------------------------------------------------");
        return pr;
    }

    private BootsProduct inputBootsProduct() {
        System.out.println("Input products here");
        String title = input.getInput();
        String priceStr = input.getParsedInput();
        System.out.println("Input size of boots");
        String size = input.getParsedInput();
        System.out.println("Input boots colors");
        String color = input.getInput();
        BootsProduct pr = new BootsProduct();
        pr.setTitle(title);
        pr.setPrice(Double.valueOf(priceStr));
        pr.setSize(Float.valueOf(size));
        pr.setColor(color);
        System.out.println("-----------------------------------------------------------");
        return pr;
    }

    private void input() {

        int dealIndex = 0, lastDealIndex = getDealsCount();

        while (dealIndex < lastDealIndex) {
            Deal d = inputDeal();
            deals.add(d);
            System.out.println("-----------<<<<<<--------Deal border------->>>>>>-----------------");
            dealIndex++;
        }
    }

    private void partyOutput() {
        System.out.println("Input number of deal what party you want to see-->");
        int dealNumber = Integer.valueOf(input.getParsedInput()) - 1;
        //Seller info output
        Deal d = deals.get(dealNumber);
        System.out.println("Seller is: " + d.getSeller() + ". Adress: " + d.getSellerObj().getAdress() + ".");
        System.out.println("***Additional seller info***");
        Set<Map.Entry<String, String>> addInfoEntry = d.getSellerObj().getAdditionalInfo().entrySet();
        for (Map.Entry<String, String> entry : addInfoEntry) {
            System.out.print(entry.getKey() + " ");
        }
        System.out.println();
        for (Map.Entry<String, String> entry : addInfoEntry) {
            System.out.print(entry.getValue() + " ");
        }
        System.out.println("\n\nBuyer is: " + d.getBuyer() + ". Adress: " + d.getBuyerObj().getAdress() + ".");
        System.out.println("***Additional buyer info***");
        addInfoEntry = d.getBuyerObj().getAdditionalInfo().entrySet();
        for (Map.Entry<String, String> entry : addInfoEntry) {
            System.out.print(entry.getKey() + " ");
        }
        System.out.println();
        for (Map.Entry<String, String> entry : addInfoEntry) {
            System.out.print(entry.getValue() + " ");
        }
    }

    private void output() {
        for (Deal d : deals) {
            System.out.println(d.getDate() + " " + d.getBuyer() + " buys from " + d.getSeller() + " with total price of " + d.getSum() + "$");
        }
    }

    private void putFotoProduct(FotoProduct fp, int quantity) {
        this.fotoProducts.put(fp, quantity);
    }

    private void putBootsProduct(BootsProduct bp, int quantity) {
        this.bootsProducts.put(bp, quantity);
    }

    private boolean isFotoProductExist(FotoProduct pr) {
        Set<FotoProduct> fotoSet = this.fotoProducts.keySet();
        for (FotoProduct fp : fotoSet) {
            if ((fp.isDigital() == pr.isDigital()) && (fp.getTitle().equals(pr.getTitle())) && (fp.getMegapx() == pr.getMegapx()) && (fp.getPrice() == pr.getPrice())) {
                return true;
            }
        }
        return false;
    }

    private boolean isBootsProductExist(BootsProduct pr) {
        Set<BootsProduct> bootSet = this.bootsProducts.keySet();
        for (BootsProduct bp : bootSet) {
            if ((bp.getSize() == pr.getSize()) && (bp.getTitle().equals(pr.getTitle())) && (bp.getColor().equals(bp.getColor())) && (bp.getPrice() == pr.getPrice())) {
                return true;
            }
        }
        return false;
    }

    /**
     * My main function. Main application logic is here. tratata
     *
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO Добавить возможность выбирать ранее введенный продукт при добавлении его в сделку.
        boolean isState = true;
        DealPconsoleGUI gui = new DealPconsoleGUI();
        DealingProgram dp = new DealingProgram();
        gui.menu();
        gui.chooseDialog();
        while (isState) {
            int menuIndex = Integer.valueOf(input.getParsedInput());
            switch (menuIndex) {
                case 1: {
                    gui.clearScreen();
                    System.out.println("Input deal count");
                    dp.setDealsCount(Integer.parseInt(input.getParsedInput()));
                    System.out.println("Input deal details");
                    dp.input();
                    gui.menu();
                    gui.chooseDialog();
                    break;
                }
                case 2: {
                    dp.partyOutput();
                    gui.chooseDialog();
                    break;
                }
                case 3: {
                    int productIndex = 1;
                    System.out.println("<--List of  products-->");
                    Set<Map.Entry<FotoProduct, Integer>> fotoSet = dp.fotoProducts.entrySet();
                    for (Map.Entry<FotoProduct, Integer> entry : fotoSet) {
                        if (entry == null) {
                            break;
                        }
                        System.out.print(productIndex++ + ". " + entry.getKey().getTitle() + " "
                                + entry.getKey().getMegapx() + " " + (entry.getKey().isDigital() ? "digital" : "analog")
                                + " " + entry.getValue());
                        System.out.println();
                    }
                    Set<Map.Entry<BootsProduct, Integer>> bootsSet = dp.bootsProducts.entrySet();
                    for (Map.Entry<BootsProduct, Integer> entry : bootsSet) {
                        if (entry == null) {
                            break;
                        }
                        System.out.print(productIndex++ + ". " + entry.getKey().getTitle() + " "
                                + entry.getKey().getSize() + " " + entry.getKey().getSize()
                                + " " + entry.getValue());
                        System.out.println();
                    }
                    gui.chooseDialog();
                    break;
                }
                case 4: {
                    System.out.println("Deal info");
                    dp.output();
                    gui.chooseDialog();
                    break;
                }
                case 5: {
                    System.out.println("Input count of products what u want to add -->");
                    int productsCount = Integer.parseInt(input.getParsedInput());
                    for (int i = 0; i < productsCount; i++) {
                        System.out.println("Input type of products (1 is photo products, 0 is shoes)");
                        if (Integer.valueOf(input.getParsedInput()) == 1) {
                            FotoProduct fp = dp.inputFotoProduct();
                            if (dp.isFotoProductExist(fp)) {
                                System.out.println("This product already exist");
                            } else {
                                int quantity = Integer.valueOf(input.getParsedInput());
                                dp.putFotoProduct(fp, quantity);
                            }
                        } else {
                            BootsProduct bp = dp.inputBootsProduct();
                            if (dp.isBootsProductExist(bp)) {
                                System.out.println("This product already exist");
                            } else {
                                int quantity = Integer.valueOf(input.getParsedInput());
                                dp.putBootsProduct(bp, quantity);
                            }
                        }
                    }
                    gui.chooseDialog();
                    break;
                }
                case 6: {
                    gui.chooseDialog();
                    break;
                }
                case 0: {
                    isState = false;
                    break;
                }
                default: {
                    System.out.println("Any options wasn't chosen, try again");
                    break;
                }
            }
        }
    }
}
